
#include "Socket.h"
#include "Engine.h"

WSADATA wsaData;

TEServer *mainServer = 0;
TEClient *mainClient = 0;

//
// InitSockets
//

void InitSockets()
{
	if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) 
	{
		//fprintf(stderr, "WSAStartup failed.\n");
		//exit(1);
	}
}

//
// CleanupSockets
//

void CleanupSockets()
{
	WSACleanup();
}




//
// TEServer
//

TEServer::TEServer()
{ 
	isValid = false;

	server = socket(AF_INET, SOCK_STREAM, 0); 

	sock.sin_family = AF_INET;
	sock.sin_addr.s_addr = INADDR_ANY;
	sock.sin_port = htons( SOCKET_PORT );

	if(bind(server, (struct sockaddr FAR *)&sock, sizeof(sock)) != SOCKET_ERROR) 
		isValid = true;

	listen(server, 200);

	WSAAsyncSelect(server, *engine.window, SERVER_ACCEPT, FD_ACCEPT);
} 

//
// ServerAccept
//

void ServerAccept(WPARAM wParam, LPARAM lParam)
{
	SOCKET sock = (SOCKET)wParam;
	WORD event = LOWORD(lParam);
	WORD error = HIWORD(lParam);
	
	if (event == FD_ACCEPT)
	{
		sockaddr_in NewRemoteSin;
		SOCKET client = accept(sock, (sockaddr*)&NewRemoteSin, NULL);

		WSAAsyncSelect(client, *engine.window, SERVER_DATA + mainServer->clients.size(), FD_READ | FD_CLOSE);
		mainServer->clients.push_back(client);

		engine.messages.push_back(Message("Client joined your server."));
		
		//SendData(client, "Hello, welcome to my server.");
	}
}

//
// ServerData
//

void ServerData(WPARAM wParam, LPARAM lParam, uint i)
{
	SOCKET sock = (SOCKET)wParam;
	WORD event = LOWORD(lParam);
	WORD error = HIWORD(lParam);

	if(event == FD_CLOSE)
	{
		closesocket(sock);
	}
	else if (event == FD_READ)
	{
		char szBuffer[1024];
		//ZeroMemory(szBuffer, 1024);
		recv(sock, szBuffer, 1024, 0);

		engine.messages.push_back(Message("Recieved data."));

		//closesocket(sock);
	}
}




//
// TEClient
//

TEClient::TEClient(const char *ip, uint len)
{ 
	isValid = false;

	localSin.sin_family = AF_INET;
	localSin.sin_port = 0;
	
	remoteSin.sin_family = AF_INET;
	remoteSin.sin_port = htons(SOCKET_PORT);

	if ((remoteSin.sin_addr.S_un.S_addr = inet_addr(ip)) == INADDR_NONE)
	{
		engine.messages.push_back(Message("Error setting IP"));
		return;		// Error setting IP
	}

	if ((client = socket(PF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
	{
		engine.messages.push_back(Message("Error creating socket"));
		return;		// Error creating socket
	}

	if (bind(client, (sockaddr *)&localSin, sizeof(sockaddr_in)) == SOCKET_ERROR)
	{
		engine.messages.push_back(Message("Error binding socket"));
		return;		// Error binding socket
	}

	if (connect(client, (sockaddr *)&remoteSin, sizeof(sockaddr_in)) == SOCKET_ERROR)
	{
		engine.messages.push_back(Message("Error connecting socket"));
		return;
	}

	WSAAsyncSelect(client, *engine.window, CLIENT_DATA, FD_READ | FD_CLOSE);

	isValid = true;
}

//
// ClientData
//

void ClientData(WPARAM wParam, LPARAM lParam)
{
	SOCKET sock = (SOCKET)wParam;
	WORD event = LOWORD(lParam);
	WORD error = HIWORD(lParam);

	if(event == FD_CLOSE)
	{
		closesocket(sock);
	}
	else if (event == FD_READ)
	{
		char szBuffer[1024];
		//ZeroMemory(szBuffer, 1024);
		recv(sock, szBuffer, 1024, 0);

		engine.messages.push_back(Message("Recieved data."));

		//closesocket(sock);
	}
}




//
// Create / Join Server
//

void Engine::CreateServer()
{
	// Check to see if one exists already
	if(mainServer || mainClient) return;

	mainServer = new TEServer();
	if(mainServer->isValid)
		messages.push_back(Message("Created server."));
	else
	{
		delete mainServer;
		mainServer = 0;
		messages.push_back(Message("Couldn't create server."));
	}
}

void Engine::JoinServer(const string &ip)
{
	// Check to see if one exists already
	if(mainServer || mainClient) return;

	mainClient = new TEClient(ip.c_str(), ip.size());
	if(mainClient->isValid)
		messages.push_back(Message("Joined server."));
	else
	{
		delete mainClient;
		mainClient = 0;
		messages.push_back(Message("Couldn't join server."));
	}
}